package deviceGroups

import (
	"context"
	"devops-super/api"
	v1 "devops-super/api/product/v1"
	"devops-super/internal/dao"
	"devops-super/internal/model/entity"
	"devops-super/internal/model/mymodel"
	"devops-super/internal/service"
	"devops-super/internal/validates"
	"errors"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gcode"
	"github.com/gogf/gf/v2/errors/gerror"
	"time"
)

// sDeviceGroup 设备分组逻辑实现
type sDeviceGroup struct{}

func init() {
	service.RegisterDeviceGroup(New())
}

// New 创建逻辑实例
func New() *sDeviceGroup {
	return &sDeviceGroup{}
}

// Add 新增设备分组
func (*sDeviceGroup) Add(ctx context.Context, in *entity.AppDeviceGroup) (err error) {

	vres := validates.ValidateDeviceGroupKey(in.GroupKey)
	if !vres {
		err = errors.New("device group key is invalid")
		return
	}

	// 检查分组标识唯一性
	count, _ := dao.AppDeviceGroup.Ctx(ctx).Where(dao.AppDeviceGroup.Columns().GroupKey, in.GroupKey).Count()
	if count > 0 {
		return errors.New("分组标识已存在")
	}

	// 检查父分组是否存在（如果指定）

	if in.ParentId > 0 {
		parentCount, _ := dao.AppDeviceGroup.Ctx(ctx).Where(dao.AppDeviceGroup.Columns().Id, in.ParentId).Count()
		if parentCount == 0 {
			return errors.New("指定的父分组不存在")
		}
	}

	// 插入分组记录
	_, err = dao.AppDeviceGroup.Ctx(ctx).Insert(in)
	return
}

// Upt 更新设备分组
func (*sDeviceGroup) Upt(ctx context.Context, in *entity.AppDeviceGroup) (err error) {

	vres := validates.ValidateDeviceGroupKey(in.GroupKey)
	if !vres {
		err = errors.New("device group key is invalid")
		return
	}

	// 检查分组标识唯一性
	count, _ := dao.AppDeviceGroup.Ctx(ctx).
		Where(dao.AppDeviceGroup.Columns().GroupKey, in.GroupKey).
		Where(dao.AppDeviceGroup.Columns().Id+" != ", in.Id).
		Count()
	if count > 0 {
		return errors.New("分组标识已存在")
	}

	// 检查父分组是否存在且不是当前分组（防止自引用）
	if in.ParentId > 0 {
		if in.ParentId == in.Id {
			return errors.New("父分组不能是当前分组本身")
		}
		parentCount, _ := dao.AppDeviceGroup.Ctx(ctx).Where(dao.AppDeviceGroup.Columns().Id, in.ParentId).Count()
		if parentCount == 0 {
			return errors.New("指定的父分组不存在")
		}
	}

	// 更新分组记录
	_, err = dao.AppDeviceGroup.Ctx(ctx).WherePri(in.Id).OmitNilData().Data(in).Update()
	return
}

// Del 删除设备分组
func (*sDeviceGroup) Del(ctx context.Context, id int) (err error) {

	// 事务处理：删除分组及关联设备
	return dao.AppDeviceGroup.Ctx(ctx).Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		// 判断是不是有子分组
		countChildren, err := dao.AppDeviceGroup.Ctx(ctx).Where(dao.AppDeviceGroup.Columns().ParentId, id).Count()
		if err != nil {
			return err
		}
		if countChildren > 0 {
			err = errors.New("should delete children groups first")
			return err
		}
		// 判断是不是有设备
		deviceCount, err := dao.AppDevice.Ctx(ctx).Where(dao.AppDevice.Columns().GroupId, id).Count()
		if err != nil {
			return err
		}
		if deviceCount > 0 {
			err = errors.New("should delete related devices first")
			return err
		}
		// 删除分组
		_, err = tx.Delete(dao.AppDeviceGroup.Table(), dao.AppDeviceGroup.Columns().Id, id)
		return err
	})
}

// GetPageLst 分页获取设备分组列表
func (*sDeviceGroup) GetPageLst(ctx context.Context, req *v1.DeviceGroupGetPageLstReq) (out *api.PageLstRes[*mymodel.AppDeviceGroupResponse], err error) {
	out = &api.PageLstRes[*mymodel.AppDeviceGroupResponse]{}
	m := dao.AppDeviceGroup.Ctx(ctx).Safe(true)

	// 部门筛选
	if req.DeptId > 0 {
		m = m.Where(dao.AppDeviceGroup.Columns().DeptId, req.DeptId)
	}

	// 名称筛选
	if req.Name != "" {
		m = m.Where(dao.AppDeviceGroup.Columns().Name+" like ? ", "%"+req.Name+"%")
	}

	// 按时间范围筛选
	if req.TimeRange != nil {
		if len(req.TimeRange) != 2 {
			return nil, gerror.NewCode(gcode.CodeInvalidParameter, "时间范围参数格式错误")
		}
		// 新增时间转换逻辑
		startTime, err := time.Parse(time.RFC3339, req.TimeRange[0])
		if err != nil {
			return nil, gerror.WrapCode(gcode.CodeInvalidParameter, err, "开始时间格式错误")
		}
		endTime, err := time.Parse(time.RFC3339, req.TimeRange[1])
		if err != nil {
			return nil, gerror.WrapCode(gcode.CodeInvalidParameter, err, "结束时间格式错误")
		}
		timeLayout := "2006-01-02 15:04:05"
		timeStr0 := startTime.Local().Format(timeLayout)
		timeStr1 := endTime.Local().Format(timeLayout)
		m = m.WhereBetween(dao.AppDeviceGroup.Columns().CreatedAt, timeStr0, timeStr1)
	}

	// 分页查询获取实体数据
	var entities []*entity.AppDeviceGroup
	count, err := m.Count()
	if err != nil {
		return nil, err
	}
	out.Total = count

	if count > 0 {
		if err = m.Offset(req.Offset()).Limit(req.Limit()).Scan(&entities); err != nil {
			return nil, err
		}

		// 转换为响应模型
		out.List = make([]*mymodel.AppDeviceGroupResponse, len(entities))

		// 收集所有部门ID
		deptIds := make([]uint64, 0)
		for _, e := range entities {
			if e.DeptId > 0 {
				deptIds = append(deptIds, uint64(e.DeptId))
			}
		}

		// 批量查询部门信息
		deptMap := make(map[uint64]string)
		if len(deptIds) > 0 {
			var depts []*entity.Dept
			if err := dao.Dept.Ctx(ctx).Where("id IN (?)", deptIds).Scan(&depts); err != nil {
				return nil, err
			}
			for _, dept := range depts {
				deptMap[uint64(dept.Id)] = dept.Name
			}
		}

		// 赋值响应数据并拼接部门名称
		for i, e := range entities {
			out.List[i] = &mymodel.AppDeviceGroupResponse{
				Id:        uint64(e.Id),
				GroupKey:  e.GroupKey,
				Name:      e.Name,
				DeptId:    uint64(e.DeptId),
				DeptName:  deptMap[uint64(e.DeptId)], // 拼接部门名称
				ParentId:  e.ParentId,
				Remark:    e.Remark,
				CreatedAt: e.CreatedAt,
				UpdatedAt: e.UpdatedAt,
				Purpose:   e.Purpose,
			}
		}
	}

	return
}

// GetOne 获取单条设备分组
func (*sDeviceGroup) GetOne(ctx context.Context, id int) (out *entity.AppDeviceGroup, err error) {
	out = new(entity.AppDeviceGroup)
	err = dao.AppDeviceGroup.Ctx(ctx).WherePri(id).Scan(&out)
	return
}

// GetOptions 获取设备分组选项
func (*sDeviceGroup) GetOptions(ctx context.Context, in *v1.DeviceGroupGetOptionsReq) (out *v1.DeviceGroupGetOptionsRes, err error) {
	data := make([]*entity.AppDeviceGroup, 0)
	m := dao.AppDeviceGroup.Ctx(ctx)
	if in.DeptId > 0 {
		m = m.Where(dao.AppDeviceGroup.Columns().DeptId, in.DeptId)
	}
	if err = m.Scan(&data); err != nil {
		return
	}
	out = new(v1.DeviceGroupGetOptionsRes)
	out.Options = data
	return
}
